package com.wanban.downloader.utils

import com.blankj.utilcode.util.CloseUtils
import com.blankj.utilcode.util.FileUtils
import com.wanban.downloader.http.HttpConnectUtils
import okhttp3.Response
import okhttp3.internal.closeQuietly
import java.io.FileOutputStream
import java.io.InputStream
import java.io.InterruptedIOException

class DownloadUtils(private val url: String,
                    private val fileNamePath: String,
                    private val listener: OnDownloadListener?,
                    private val headers: Map<String, String>? = null): Runnable {

    interface OnDownloadListener {
        fun onProgress(url: String, progress: Int)
        fun onError(url: String, errorMsg: String)
        fun onComplete(url: String, totalLength: Long)
    }

    override fun run() {
        // 检查是否能正常创建下载文件
        val isCreateFile = FileUtils.createFileByDeleteOldFile(fileNamePath)
        if (!isCreateFile) {
            listener?.onError(url, "下载失败，无法创建下载文件！")
            return
        }
        listener?.onProgress(url, 0)
        val response: Response?
        val inputStream: InputStream?
        var fileOutputStream: FileOutputStream? = null
        val httpConnectUtils = HttpConnectUtils()
        try {
            response = httpConnectUtils.open(url, headers)
        } catch (e: Exception) {
            if (e is InterruptedIOException) return
            listener?.onError(url, "下载出错，视频地址无法访问，CODE:11！")
            return
        }

        val responseBody = response?.body
        if (responseBody == null) {
            response?.closeQuietly()
            listener?.onError(url, "下载出错，视频地址无法访问，CODE:12！")
            return
        }
        val mTotalLength = responseBody.contentLength() //下载文件的总长度
        var len: Int
        var contentLength = 0L
        val bytes = ByteArray(4096)
        inputStream = responseBody.byteStream()
        try {
            fileOutputStream = FileOutputStream(fileNamePath)
            while (inputStream.read(bytes).also { len = it } != -1) {
                contentLength += len
                fileOutputStream.write(bytes, 0, len)
                // 完成回调
                listener?.onProgress(url, len)
            }
            if (contentLength != mTotalLength) { // 下载不完整
                listener?.onError(url, "下载出错，视频地址无法访问，CODE:13！")
                return
            }
            // 完成回调
            listener?.onComplete(url, mTotalLength)
        } catch (e: Exception) {
            if (e is InterruptedIOException) return
            listener?.onError(url, "下载出错，视频地址无法访问，CODE:14！")
        } finally {
            CloseUtils.closeIOQuietly(response, inputStream, fileOutputStream)
        }
    }

}